import { reactive, watch, onMounted, isRef } from 'vue'
import _ from 'lodash'

export default function useTree(
  proxy,
  options = {
    tree: {
      ref: 'tree',
      nodeKey: 'id',
      propConfig: { children: undefined, label: undefined },
      click: { before: undefined, after: undefined }
    },
    action: {
      query: {
        api: undefined,
        params: undefined,
        before: undefined,
        after: undefined
      },
      queryChecked: {
        api: undefined,
        params: undefined,
        before: undefined,
        after: undefined
      },
      saveChecked: {
        api: undefined,
        before: undefined,
        after: undefined,
        params: undefined,
        tips: undefined
      }
    }
  }
) {
  const tree = reactive({
    data: [],
    checked: [],
    clickNode: {}
  })

  const filterText = ref('')

  watch(filterText, (val) => {
    // console.log('filterText watch')
    proxy.$refs[options.tree.ref].filter(val)
  })

  function filterTreeNode(val, data) {
    return !val || data[options.tree.propConfig.label].includes(val)
  }

  function filterLeafNode(array) {
    let result = []
    for (const item of array) {
      if (item.children && item.children.length > 0) {
        result = result.concat(filterLeafNode(item.children))
      } else {
        result.push(item.id)
      }
    }
    return result
  }

  function fetchTree() {
    const params = _.isFunction(options.action.query.before)
      ? options.action.query.before()
      : options.action.query.params
    options.action.query.api(params).then((res) => {
      tree.data = res.data || []
      if (_.isFunction(options.action.query?.after)) {
        options.action.query.after(res)
      }
    })
  }

  function expandAll() {
    for (const item of tree.data) {
      proxy.$refs[options.tree.ref].store.nodesMap[
        item[options.tree.nodeKey]
      ].expanded = true
    }
  }

  function foldAll() {
    for (const item of tree.data) {
      proxy.$refs[options.tree.ref].store.nodesMap[
        item[options.tree.nodeKey]
      ].expanded = false
    }
  }

  function clickNode(node) {
    // console.log('clickNode')
    if (_.isFunction(options.tree.click?.before)) {
      options.tree.click.before()
    }
    tree.clickNode = node
    if (_.isFunction(options.tree.click?.after)) {
      options.tree.click.after()
    }
  }

  function fetchChecked(data) {
    if (_.isFunction(options.action.query?.before)) {
      options.action.query.before(data)
    }
    options.action.queryChecked
      .api(options.action.queryChecked.params(data))
      .then((res) => {
        tree.checked = filterLeafNode(res.data || [])
        proxy.$refs[options.tree.ref].setCheckedKeys(tree.checked, true)
        if (_.isFunction(options.action.query?.after)) {
          options.action.query.after(res)
        }
      })
  }

  function saveChecked() {
    if (!_.isFunction(options.action.saveChecked.params)) {
      return
    }
    options.action.saveChecked
      .api(options.action.saveChecked.params())
      .then((res) => {
        proxy.$modal.msgSuccess(options.action.saveChecked.tips || '保存成功')
        fetchChecked()
      })
  }

  function clearTreeChecked() {
    // console.log('clearCurrentKey')
    proxy.$refs[options.tree.ref].setCurrentKey([], true)
  }

  onMounted(() => {
    console.log('useTree hook mounted!')
  })

  return {
    tree,
    filterText,
    filterTreeNode,
    filterLeafNode,
    fetchTree,
    fetchChecked,
    saveChecked,
    clearTreeChecked,
    expandAll,
    foldAll,
    clickNode
  }
}
